<template>
    <div>
        <!-- 公共上传方法 -->
        <input type="file" hidden v-bind="params" @change="onChange" ref="file" />
    </div>
</template>

<script>
import { throttle } from 'lodash';
import { resolvePath } from '../utils/path';
import { cloneDeep } from 'lodash';

export class FileData {
    constructor(params) {
        this.params = params;
    }

    params; // eslint-disable-line

    resp = null;

    progress = 0;

    status = 'waiting';

    client = null;

    checkpoint = null;

    dataSource = 'rawa';
}

export default {
    props: {
        limitParams: {
            type: Object,
            default: () => {}
        },
        fileTypeMap: {
            type: Object,
            default: () => {}
        },
        moduleType: {
            type: String,
            default: 'pms' //所属模块 可用值:cms,crm,fms,hrs,pms,scs,tss
        },
        limit: {
            type: Number,
            default: 6
        }
    },
    data() {
        return {
            params: {},
            parent: null, //包含docId => parentId
            load: '',
            queue: [],
            fileTypeData: {} //保存上传的文件类型和数量
        };
    },
    methods: {
        open(params, parent) {
            this.params = params || {};
            this.parent = parent || null;
            this.$refs.file.value = '';
            this.$nextTick(() => {
                this.$refs.file.click();
            });
        },
        async onChange(value) {
            if (await this.uploadConfirm(this.$refs.file.files, this.parent?.docId)) {
                const files = this.$refs.file.files;
                this.uploadFiles(files, this.parent, this.load); //file-upload-mixins
            }
        },
        async uploadConfirm(files, parentId) {
            const rootDir = getRootDir(files);
            if (rootDir) {
                const exists = await existsName(parentId, rootDir);
                if (exists) {
                    if (
                        !(await this.$confirm(`该文件夹【${rootDir}】已存在，是否要覆盖?`, '提示')
                            .then(() => true)
                            .catch(() => false))
                    ) {
                        return false;
                    }
                }
            }
            return true;

            function getRootDir(files) {
                const file = files[0];
                const path = file?.webkitRelativePath;
                const seg = (path || '').split('/');
                return seg.length > 1 ? seg[0] : '';
            }
        },
        /* 文件上传方法 file-upload-mixins */
        uploadFiles(files, parent, load) {
            const _throttleLoadFn = throttle(
                () => {
                    if (load) load();
                },
                2 * 1000,
                { leading: false }
            );

            // 限定单次批量上传数量 limit
            if (files.length > this.limit) return this.$message.warning(`单次批量上传最大为${this.limit}个`);

            for (let i = 0; i < files?.length; i++) {
                const item = files[i];
                const params = {
                    name: item.name,
                    file: item,
                    path: parent?.path,
                    actualPath: resolvePath(parent?.path || '', item.webkitRelativePath || item.name, '..'),
                    parentId: parent?.docId, //文档或者单据id
                    moduleType: this.moduleType,
                    beforeUpload: (params, queue) => {
                        const name = params.file.webkitRelativePath || params.name;
                        const has = queue.some((v) => {
                            const vname = v?.params?.file?.webkitRelativePath || v?.params?.name;
                            // 判断相同文件依据 name和parentId都想等 目前组件parentId都是undefined
                            return name === vname && params.parentId === v?.params?.parentId && ['uploading', 'waiting', 'cancel'].includes(v.status);
                        });
                        // Promise.reject
                        const handleMsg = (msg) => {
                            this.$message.warning(msg);
                            return Promise.reject(new Error(msg));
                        };
                        if (has) {
                            return handleMsg('任务已在列表中');
                        }

                        // 限定上传 limitParams
                        const types = params.file.name.split('.');
                        const type = types[types.length - 1].replace('.', '');
                        let bool = false;
                        try {
                            Object.keys(this.limitParams).forEach((key) => {
                                if (Array.isArray(this.limitParams[key])) {
                                    this.limitParams[key].forEach((item) => {
                                        if (item.type.includes(type)) {
                                            bool = true;
                                            this.fileTypeData = cloneDeep(item);
                                            this.fileTypeData.key = key;
                                            throw Error();
                                        }
                                    });
                                } else {
                                    if (this.limitParams[key].type.includes(type)) {
                                        bool = true;
                                        this.fileTypeData = cloneDeep(this.limitParams[key]);
                                        this.fileTypeData.key = key;
                                        throw Error();
                                    }
                                }
                            });
                        } catch (e) {
                            console.log(e);
                        }

                        if (!bool) {
                            return handleMsg('当前文件不允许上传');
                        } else {
                            // 判断尺寸
                            const size = params.file.size / 1024 / 1024;
                            if (size > this.fileTypeData.maxSize) {
                                return handleMsg(`当前文件单个文件大小不能超出${this.fileTypeData.maxSize}M`);
                            }
                            // 判断数量
                            if (this.fileTypeData.currentNum >= this.fileTypeData.maxNum) {
                                return handleMsg(`当前文件类型最多上传${this.fileTypeData.maxNum}个`);
                            }
                        }

                        return Promise.resolve();
                    },
                    afterUpload: (params, resp, queue) => {
                        this.$oss.queue = queue; // 赋值更新queue数据
                        this.$emit('handle-success', resp.data.response, this.fileTypeData);
                        return new Promise((resolve, reject) => {
                            resolve(resp);
                        }).then((data) => {
                            return data;
                        });
                        // let getUrl = resp?.data?.res?.dealUrl;

                        // const name = params.file.webkitRelativePath || params.name;
                        // const req = {
                        //     parentId: params.parentId,
                        //     name: name,
                        //     size: params.file?.size,
                        //     url: getUrl.endsWith('dwg') || getUrl.endsWith('dxf') ? getUrl : resp.url
                        // };

                        // return upload(req).then((data) => {
                        //     const normal = this.$route?.query?.id === String(params.parentId) && name.indexOf('/') === -1;
                        //     const root = !this.$route?.query?.id && params.path.indexOf('/') < 0 && name.indexOf('/') === -1;
                        //     if (load && (normal || root)) {
                        //         _throttleLoadFn();
                        //     }
                        //     return data;
                        // });
                    }
                };
                this.$oss.upload(params);
            }
        }
    }
};
</script>
